from typing import List, Optional
from datetime import datetime
try:
    from typing import Annotated  # Python 3.9+
except ImportError:
    from typing_extensions import Annotated  # Python 3.7+
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from app import crud
from app.api import deps
from app.schemas.user import User
from app.schemas.learning import (
    LearningPlan,
    LearningPlanCreate,
    LearningPlanUpdate,
    LearningTask,
    LearningTaskCreate,
    LearningTaskUpdate,
    Progress,
    ProgressCreate,
    KnowledgeBase,
)

router = APIRouter()

# Knowledge Base routes
@router.get("/knowledge", response_model=dict)
# @router.get("/knowledge", response_model=List[KnowledgeBase])  # 暂时使用dict以便调试
# @router.get("/knowledge", response_model=dict[str, Union[List[KnowledgeBase], int]])
def get_knowledge_list(  # 获取知识点列表，可按科目和级别筛选
    *,
    db: Session = Depends(deps.get_db),
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(10, ge=1, le=100, description="返回的记录数"),
    subject: Optional[str] = Query(None, description="按科目筛选"),
    level: Optional[str] = Query(None, pattern="^(初级|中级|高级)$", description="按级别筛选"),
    current_user: User = Depends(deps.get_current_active_user),
) -> dict:
    """获取知识点列表，可按科目和级别筛选"""
    try:
        # 打印请求信息，帮助调试
        print(f"Request params - skip: {skip}, limit: {limit}, subject: {subject}, level: {level}")
        print(f"Current user: {current_user.id} - {current_user.email}")

        # 确保分页参数合法
        skip = max(0, skip)
        limit = min(100, max(1, limit))

        # 检查数据库连接
        try:
            from sqlalchemy import text
            db.execute(text("SELECT 1"))
        except Exception as e:
            print(f"Database connection error: {e}")
            raise HTTPException(
                status_code=500,
                detail="数据库连接失败，请检查数据库状态"
            )

        # 获取知识点列表
        knowledge_list = crud.learning.get_knowledge_multi(
            db, skip=skip, limit=limit, subject=subject, level=level
        )

        # 计算总数
        from app.models.learning import KnowledgeBase as KnowledgeBaseModel
        total_count = db.query(KnowledgeBaseModel).count()

        # 打印结果信息，帮助调试
        print(f"Found {len(knowledge_list)} knowledge items, total: {total_count}")

        # 确保返回的是可序列化的数据
        from app.schemas.learning import KnowledgeBase as KnowledgeBaseSchema
        knowledge_data = [
            KnowledgeBaseSchema.model_validate(item) for item in knowledge_list
        ]

        # 手动将SQLAlchemy模型对象转换为字典
        knowledge_data = []
        for item in knowledge_list:
            knowledge_data.append({
                "id": item.id,
                "subject": item.subject,
                "level": item.level,
                "chapter": item.chapter,
                "knowledge_point": item.knowledge_point,
                "content": item.content,
                "extended_content": item.extended_content,
                "study_count": item.study_count,
                "is_course": item.is_course,
                "title": item.title,
                "description": item.description,
                "credits": item.credits,
                "duration": item.duration,
                "prerequisites": item.prerequisites,
                "created_at": item.created_at.isoformat() if item.created_at else datetime.utcnow().isoformat(),
                "updated_at": item.updated_at.isoformat() if item.updated_at else datetime.utcnow().isoformat()
            })

        return {
            "data": knowledge_data,
            "total": total_count,
            "skip": skip,
            "limit": limit
        }
    except HTTPException:
        raise
    except Exception as e:
        import traceback
        print(f"Error in get_knowledge_list: {str(e)}")
        print(f"Traceback: {traceback.format_exc()}")
        raise HTTPException(
            status_code=500,
            detail=f"获取知识点列表失败：{str(e)}"
        )

@router.post("/knowledge/{knowledge_id}/enroll")
def enroll_knowledge(
    *,
    db: Session = Depends(deps.get_db),
    knowledge_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> dict:
    """选择学习特定知识点"""
    result = crud.learning.enroll_knowledge(
        db, user_id=current_user.id, knowledge_id=knowledge_id
    )
    if result:
        return {"status": "success", "message": "Successfully enrolled"}
    raise HTTPException(status_code=400, detail="Enrollment failed")

@router.delete("/knowledge/{knowledge_id}/enroll")
def cancel_knowledge_enrollment(
    *,
    db: Session = Depends(deps.get_db),
    knowledge_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> dict:
    """取消选择学习特定知识点"""
    result = crud.learning.cancel_knowledge_enrollment(
        db, user_id=current_user.id, knowledge_id=knowledge_id
    )
    if result:
        return {"status": "success", "message": "Successfully canceled enrollment"}
    raise HTTPException(status_code=400, detail="Cancellation failed")

@router.post("/knowledge/generate-plan")
def generate_learning_plan(
    *,
    db: Session = Depends(deps.get_db),
    knowledge_ids: List[int],
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningPlan:
    """基于选择的知识点生成学习计划"""
    plan = crud.learning.generate_learning_plan(
        db, user_id=current_user.id, knowledge_ids=knowledge_ids
    )
    if not plan:
        raise HTTPException(status_code=400, detail="Failed to generate learning plan")
    return plan

@router.get("/knowledge/enrolled", response_model=List[KnowledgeBase])
def get_enrolled_knowledge(
    *,
    db: Session = Depends(deps.get_db),
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> List[KnowledgeBase]:
    """获取用户已选择的知识点列表"""
    enrolled_knowledge = crud.learning.get_enrolled_knowledge(
        db, user_id=current_user.id, skip=skip, limit=limit
    )
    return enrolled_knowledge

# Learning Plan routes
@router.post("/learning-plans", response_model=LearningPlan)
def create_learning_plan(
    *,
    current_user: Annotated[User, Depends(deps.get_current_active_user)],
    db: Annotated[Session, Depends(deps.get_db)],
    plan_in: LearningPlanCreate,
    course_id: Optional[int] = Query(None, description="关联的课程ID，如果提供则基于课程创建学习计划")
) -> LearningPlan:
    """创建新学习计划，可选择基于课程创建"""
    plan = crud.learning.create_learning_plan(
        db,
        plan_in=plan_in,
        user_id=current_user.id,
        course_id=course_id
    )
    return plan

@router.get("/learning-plans", response_model=List[LearningPlan])
def get_learning_plans(
    db: Session = Depends(deps.get_db),
    skip: int = 0,
    limit: int = 100,
    status: Optional[str] = None,
    current_user: User = Depends(deps.get_current_active_user),
) -> List[LearningPlan]:
    """获取当前用户的学习计划列表"""
    try:
        print(f"获取用户 {current_user.id} 的学习计划列表")
        plans = crud.learning.get_learning_plans(
            db, user_id=current_user.id, skip=skip, limit=limit, status=status
        )
        print(f"成功获取到 {len(plans)} 个学习计划")
        return plans
    except Exception as e:
        import traceback
        print(f"获取学习计划时出错: {str(e)}")
        print(f"错误详情: {traceback.format_exc()}")
        raise HTTPException(
            status_code=500,
            detail=f"获取学习计划失败: {str(e)}"
        )

@router.get("/learning-plans/{plan_id}", response_model=LearningPlan)
def get_learning_plan(
    *,
    db: Session = Depends(deps.get_db),
    plan_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningPlan:
    """获取特定学习计划的详细信息"""
    plan = crud.learning.get_learning_plan(db, plan_id=plan_id)
    if not plan:
        raise HTTPException(status_code=404, detail="Learning plan not found")
    if plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    return plan

@router.put("/learning-plans/{plan_id}", response_model=LearningPlan)
def update_learning_plan(
    *,
    db: Session = Depends(deps.get_db),
    plan_id: int,
    plan_in: LearningPlanUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningPlan:
    """更新学习计划"""
    plan = crud.learning.get_learning_plan(db, plan_id=plan_id)
    if not plan:
        raise HTTPException(status_code=404, detail="Learning plan not found")
    if plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    plan = crud.learning.update_learning_plan(db, db_obj=plan, obj_in=plan_in)
    return plan

@router.delete("/learning-plans/{plan_id}")
def delete_learning_plan(
    *,
    db: Session = Depends(deps.get_db),
    plan_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> dict:
    """删除学习计划"""
    plan = crud.learning.get_learning_plan(db, plan_id=plan_id)
    if not plan:
        raise HTTPException(status_code=404, detail="Learning plan not found")
    if plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    crud.learning.delete_learning_plan(db, plan_id=plan_id)
    return {"status": "success"}

# Learning Task routes
@router.post("/learning-plans/{plan_id}/tasks", response_model=LearningTask)
def create_task(
    *,
    db: Session = Depends(deps.get_db),
    plan_id: int,
    task_in: LearningTaskCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningTask:
    """为学习计划创建新任务"""
    plan = crud.learning.get_learning_plan(db, plan_id=plan_id)
    if not plan:
        raise HTTPException(status_code=404, detail="Learning plan not found")
    if plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    task = crud.learning.create_task(db, task_in=task_in)
    return task

@router.get("/learning-plans/{plan_id}/tasks", response_model=List[LearningTask])
def get_tasks(
    *,
    db: Session = Depends(deps.get_db),
    plan_id: int,
    skip: int = 0,
    limit: int = 100,
    status: Optional[str] = None,
    current_user: User = Depends(deps.get_current_active_user),
) -> List[LearningTask]:
    """获取学习计划的任务列表"""
    plan = crud.learning.get_learning_plan(db, plan_id=plan_id)
    if not plan:
        raise HTTPException(status_code=404, detail="Learning plan not found")
    if plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    tasks = crud.learning.get_plan_tasks(
        db, plan_id=plan_id, skip=skip, limit=limit, status=status
    )
    return tasks

@router.get("/tasks/{task_id}", response_model=LearningTask)
def get_task(
    *,
    db: Session = Depends(deps.get_db),
    task_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningTask:
    """获取特定任务的详细信息"""
    task = crud.learning.get_task(db, task_id=task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    if task.plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    return task

@router.put("/tasks/{task_id}", response_model=LearningTask)
def update_task(
    *,
    db: Session = Depends(deps.get_db),
    task_id: int,
    task_in: LearningTaskUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningTask:
    """更新任务"""
    task = crud.learning.get_task(db, task_id=task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    if task.plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    task = crud.learning.update_task(db, db_obj=task, obj_in=task_in)
    return task

@router.post("/tasks/{task_id}/start", response_model=LearningTask)
def start_learning_task(
    *,
    db: Session = Depends(deps.get_db),
    task_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> LearningTask:
    """开始学习任务"""
    task = crud.learning.get_task(db, task_id=task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    if task.plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")

    from datetime import datetime, timedelta
    now = datetime.utcnow()
    task_update = LearningTaskUpdate(
        start_date=now,
        due_date=now + timedelta(hours=24),
        status="in_progress"  # 使用英文状态值，确保前后端一致
    )
    updated_task = crud.learning.update_task(db, db_obj=task, obj_in=task_update)
    return updated_task

@router.delete("/tasks/{task_id}")
def delete_task(
    *,
    db: Session = Depends(deps.get_db),
    task_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> dict:
    """删除任务"""
    task = crud.learning.get_task(db, task_id=task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    if task.plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    crud.learning.delete_task(db, task_id=task_id)
    return {"status": "success"}

# Progress routes
@router.post("/tasks/{task_id}/progress", response_model=Progress)
def create_progress(
    *,
    db: Session = Depends(deps.get_db),
    task_id: int,
    progress_in: ProgressCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Progress:
    """记录任务进度"""
    task = crud.learning.get_task(db, task_id=task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    if task.plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    progress = crud.learning.create_progress(
        db, progress_in=progress_in, user_id=current_user.id
    )
    return progress

@router.get("/tasks/{task_id}/progress", response_model=List[Progress])
def get_task_progress(
    *,
    db: Session = Depends(deps.get_db),
    task_id: int,
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> List[Progress]:
    """获取任务的进度历史"""
    task = crud.learning.get_task(db, task_id=task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    if task.plan.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    progress = crud.learning.get_task_progress(db, task_id=task_id, skip=skip, limit=limit)
    return progress

@router.get("/users/me/progress", response_model=List[Progress])
def get_user_progress(
    *,
    db: Session = Depends(deps.get_db),
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> List[Progress]:
    """获取用户的所有进度记录"""
    progress = crud.learning.get_user_progress(
        db, user_id=current_user.id, skip=skip, limit=limit
    )
    return progress